<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    * {
      padding: 0;
      margin: 0;

    }

    li {
      list-style: none;
    }

    #app {
      width: 100%;
      margin-left: 300px;
      justify-content: center;

    }

    .item-box {
      width: 200px;
    }

    .search-input {
      margin: 20px 0;
    }

    .arrow-box {
      display: inline-block;
      width: 12px;
      height: 12px;
    }

    .arrow-img {
      width: 12px;
      height: 12px;
    }

    .active {
      background: cyan;
    }
  </style>

</head>

<body>
  <!--1. 实现一个多层级目录树组件-->
  <!--点击左侧图标能 收起/展开 节点，图标会根据节点的状态 表现不同样式-->
  <!--要求暴露给父组件一个事件，点击时候，父组件能通过监听对应的事件，知道点击了哪个节点-->
  <!--示例图-->

  <!--2. 如果要支持搜索功能，通过搜索框的输入项，定位到对应节点，高亮显示-->
  <!--只需要字符串匹配对应节点展示文案即可-->
  <!--要求输入内容和对应节点文案完全匹配-->
  <!--示例图-->
  <!--输入前-->

  <div id="app">
    <input v-model="search" type="text" @blur="findTree($event)" class="search-input">
    <ul class="tree-list">
      <tree-list v-for="(item,index) in node " :key="index" :item="item" @change-active="changeActive"></tree-list>
    </ul>


  </div>


  <!--组件模板-->
  <script type="text/x-template" id="tree-template">

    <li :style="offsetLeft">
        <div :class="[item.active?'active':'']" class="item-box">
                <span class="arrow-box" @click="changeOpen(item)">
<!--                    <img src="./image/right.png" v-if="!item.isOpen&&item.children" class="arrow-img" alt="">-->
<!--                    <img src="./image/bottom.png" v-if="item.isOpen&&item.children" class="arrow-img" alt="">-->
                    <span  v-if="!item.isOpen&&item.children" class="arrow-img"> > </span>
                    <span src="./image/bottom.png" v-if="item.isOpen&&item.children" class="arrow-img" > v </span>
                </span>
            <span @click="changeActive(item)">{{item.text}}</span>
        </div>


        <ul class="tree-list" v-show="item.isOpen" v-if="item.children">
            <tree-list v-for="(item,index) in item.children " :key="index" :item="item"
                       @change-active="changeActive"></tree-list>
        </ul>
    </li>

</script>


  <!--引入vue,js-->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
  <!--引入JQ-->
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <script>
    window.onload = function () {
      //注册全局组件
      Vue.component('tree-list', {
        template: '#tree-template',
        props: ['item'],//接受数据
        data: function () {
          return {
            offsetLeft: ''
          }
        },

        methods: {
          // 展开收起
          changeOpen(_data) {
            console.log(_data)
            if (!_data.children) return
            _data.isOpen = !_data.isOpen
          },
          changeActive(_data) {
            this.$emit('change-active', _data)
          },
          // 使用JQ 计算左偏移量
          countLeft() {
            // console.log(this.$el)
            var num = $(this.$el).parents('.tree-list').length
            this.offsetLeft = 'padding-left:' + num * 5 + 'px'
            // console.log(this.offsetLeft)
          }
        },
        mounted() {
          this.countLeft()
        },

      })
      // 构建vue实例
      new Vue({
        el: '#app',
        data: {
          node: [{
            id: '1', // 节点ID hello world 1
            text: 'hello world 1', // 节点展示文案
            children: [{ // 节点子元素
              id: '1-1',
              text: 'hello world 1-1',
              children: [{
                // ...
                id: '1-1-1',
                text: 'hello world 1-1-1',
              }],
            }]
          }, { id: '2', text: 'hello world 2', }],
          search: ''
        },
        mounted() {
          this.init(this.node)
        },
        methods: {
          // 初始化数据
          init(_data) {
            console.log('执行了')
            // isOpen 是否展开
            // active 是否选中
            function setAttr(_data) {
              _data.forEach(item => {

                Vue.set(item, 'isOpen', false)
                Vue.set(item, 'active', false)
                if (item.children) {
                  setAttr(item.children)
                }
              })

            }

            setAttr(_data)
            this.node = _data
            // this.$forceUpdate()
            console.log(this)
          },

          // 是否选中
          changeActive(_data) {
            if (_data.active) return // 点击元素已经选中 直接返回
            this.reset(this.node)

            _data.active = true
          },

          // 重置结构数据
          reset(_data) {
            function activeReset(_data) {
              _data.forEach(item => {
                item.active = false

                if (item.children) {
                  activeReset(item.children)
                }
              })
            }

            activeReset(_data)
          },
          // 搜索功能
          findTree(e) {
            this.reset(this.node)
            var searchVal = e.target._value
            function activeReset(_data, val) {
              _data.forEach(item => {
                console.log(item.text == val)
                if (item.text == val) {
                  item.active = true
                }


                if (item.children) {
                  activeReset(item.children, val)
                }
              })
            }

            activeReset(this.node, searchVal)

          }


        }

      })
    }


  </script>


</body>

</html>